﻿using Castle.Core.Logging;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Castle.Windsor.Installer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WJP.Dependency;
using WJP.Runtime.Validation;

namespace WJP.Logging
{
    /// <summary>
    /// 日志管理
    /// </summary>
    public static class LogManager
    {
        /// <summary>
        /// 系统日志记录器
        /// </summary>
        public static ILogger Logger { get; private set; }

        /// <summary>
        /// 日志管理
        /// </summary>
        static LogManager()
        {
            IocManager.Instance.Register<ILoggerFactory, StreamLoggerFactory>();
            Logger = IocManager.Instance.Resolve<ILoggerFactory>().Create(typeof(LogManager));
        }

        public static void RegisterLoggerFactory(ILoggerFactory loggerFactory)
        {
            IocManager.Instance.IocContainer
                .Register(Component.For<ILoggerFactory>().Instance(loggerFactory).IsDefault());
        }

        public static ILogger GetLogger(Type type)
        {
            return IocManager.Instance.Resolve<ILoggerFactory>().Create(type);
        }

        public static ILogger GetLogger<T>()
        {
            return GetLogger(typeof(T));
        }

        public static ILogger GetLogger(string name)
        {
            var factor = IocManager.Instance.Resolve<ILoggerFactory>();
            return factor.Create(name);
        }

        public static void LogException(Exception ex)
        {
            LogException(Logger, ex);
        }

        public static void LogException(ILogger logger, Exception ex)
        {
            var severity = (ex as IHasLogLevel)?.Level ?? LogLevel.Error;

            logger.Log(severity, ex.Message, ex);

            LogValidationErrors(logger, ex);
        }

        private static void LogValidationErrors(ILogger logger, Exception exception)
        {
            if (exception is AggregateException && exception.InnerException != null)
            {
                var aggException = exception as AggregateException;
                if (aggException.InnerException is AppValidationException)
                {
                    exception = aggException.InnerException;
                }
            }

            if (!(exception is AppValidationException))
            {
                return;
            }

            var validationException = exception as AppValidationException;
            if (validationException.ValidationErrors.IsNullOrEmpty())
            {
                return;
            }

            logger.Log(validationException.Level, "有{0}个验证错误：".FormatArgs(validationException.ValidationErrors.Count));
            foreach (var validationResult in validationException.ValidationErrors)
            {
                var memberNames = "";
                if (validationResult.MemberNames != null && validationResult.MemberNames.Any())
                {
                    memberNames = " (" + string.Join(", ", validationResult.MemberNames) + ")";
                }

                logger.Log(validationException.Level, validationResult.ErrorMessage + memberNames);
            }
        }
    }
}
